﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ChiakiYu.Model.Permissions;
using ChiakiYu.Service.Authorization;

namespace ChiakiYu.Web.Controllers.Filters
{
    /// <summary>
    ///     后台身份验证
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
    public class PermissionAuthorizeAttribute : FilterAttribute, IAuthorizationFilter
    {

        public void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }
            HasPermission(filterContext);

        }

        /// <summary>
        /// 当前请求是否具有访问权限
        /// </summary>
        /// <param name="filterContext"></param>
        /// <returns></returns>
        private void HasPermission(AuthorizationContext filterContext)
        {
            if (UserContext.CurrentUser == null)
            {
                //filterContext.Controller.TempData["StatusMessageData"] = "请以管理员身份登录！";
                //filterContext.Result = new RedirectResult("~/Admin/ManageLogin");
                return;
            }

            if (UserContext.CurrentUser.UserName == "admin")//超级管理员拥有所有权限
                return;
            //取当前用户的权限
            var rolePermissions = GetUserPermissions(filterContext.HttpContext);
            //待访问的Action的Permission
            var action = new Permission
            {
                Action = filterContext.ActionDescriptor.ActionName,
                Controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName,
                ActionDescription = ActionPermissionService.GetAttribute(filterContext.ActionDescriptor).Description,
                ControllerDescription = ActionPermissionService.GetAttribute(filterContext.ActionDescriptor.ControllerDescriptor).Description
            };
            //是否授权
            var hasPermission = true;
            if (ActionPermissionService.GetAllActionByAssembly().Contains(action, new PermissionEqualityComparer()))
            {
                hasPermission = rolePermissions.Contains(action, new PermissionEqualityComparer());
            }
            if (!hasPermission)
            {
                if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
                {
                    filterContext.Controller.TempData["StatusMessageData"] = string.Format("您没有{0}的权限！", action.ActionDescription);
                    filterContext.Result = new RedirectResult("~/NoPermission");
                }
                else
                {
                    filterContext.Controller.TempData["StatusMessageData"] = string.Format("您没有{0}的权限！", action.ActionDescription);
                    filterContext.Result = new RedirectResult("~/Admin/Home");
                }
            }
        }

        /// <summary>
        /// 取当前用户的权限列表
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private IEnumerable<Permission> GetUserPermissions(HttpContextBase context)
        {
            //取用户Id和Name
            var userId = UserContext.CurrentUser.Id;
            var userName = UserContext.CurrentUser.UserName;
            //构建缓存key
            var key = string.Format("UserPermissions_{0}", userName);
            //从缓存中取权限
            var permissions = HttpContext.Current.Session[key] as IEnumerable<Permission>;
            //若没有，则从db中取并写入缓存
            if (permissions == null)
            {

                var authorizationService = DependencyResolver.Current.GetService<IAuthorizationService>();
                //取用户权限集合
                permissions = authorizationService.GetUserPermissions(userId);
                //写入缓存
                context.Session.Add(key, permissions);
            }
            return permissions;
        }

    }
}